鐵匠史密斯在此~
昨日已經知道了視角的轉動速率與硬體規格,也就是影格刷新速率(frame rate = fps) 有關
我們今天直接上Code吧~
chrono
來得出影格刷新速率吧!std::chrono
是一個 C++ 11
後建立的套件,以物件導向的方式來記錄時間戳以及時間的處理(sleep, 秒、毫秒轉換等等),詳情可以見Refernce處的 Cpp Reference: Date and time library 以及 Heresy's Space: C++11 STL 的時間函式庫:chrono
由於我們的主控台畫面緩衝區 screen
是將一格一格畫面呈現在螢幕上的
這就是目前第一層 while
迴圈的作用
所以,我們需要在每一個 while
迴圈,也就是影格刷新的時候,去紀錄到下一張影格需要花多少時間
// Create world map
std::wstring map{};
map += L"################";
map += L"#..............#";
map += L"#..............#";
map += L"#..............#";
map += L"#..............#";
map += L"#..............#";
map += L"#..............#";
map += L"#..............#";
map += L"#..............#";
map += L"#..............#";
map += L"#..............#";
map += L"#..............#";
map += L"#..............#";
map += L"#..............#";
map += L"#..............#";
map += L"################";
// Get two time point to get frame rate
auto tp1 { chrono::system_clock::now() };
auto tp2 { chrono::system_clock::now() };
while (true) {
...
初始化了兩個時間戳 tp1
以及 tp2
,以便在刷新影格時(while
迴圈內) 紀錄時間差
// Get two time point to get frame rate
auto tp1 { chrono::system_clock::now() };
auto tp2 { chrono::system_clock::now() };
while (true) {
// Get frame rate per loop
tp2 = chrono::system_clock::now();
chrono::duration<float> elaspedTime = tp2 - tp1;
tp1 = tp2;
float fElaspedTime{ elaspedTime.count() };
...
紀錄末時間點 tp2
而得出時間差 elaspedTime
= 末時間點 - 初時間點 = tp2 - tp1
再把初時間點 tp1
賦值成當下的末時間點 tp2
,以便為下一輪迴圈(影格)的初始時間點
這裡簡單說明:chrono::duration<float> elaspedTime
是一個儲存資料的型別,如果要使這個型別儲存 float
的話,就是儲存以 float
為單位的秒數:
#include <iostream>
#include <chrono>
using namespace std;
int main(){
auto tp1 { chrono::system_clock::now() };
std::cout << "Hello World\n";
auto tp2 { chrono::system_clock::now() };
chrono::duration<float> elaspedTime = tp2 - tp1;
std::cout << "Printing took "
<< elaspedTime.count()
<< " for second" << std::endl;
return 0;
}
顯示的結果為:
所以,可以回到 main()
函式內,我們知道了時間差,從昨日的Day 19 文章,我可以藉由時間差,也就是週期 T
, 來調節影格刷新速率 f
,那我們在**每格影格刷新時,按特定按鈕 (Q
、 A
)後,所調整的角度如下: **
// Controls
// Handle rotation
if (GetAsyncKeyState((unsigned short)'Q') & 0x8000)
fPlayerA += (0.1f) * fElaspedTime;
if (GetAsyncKeyState((unsigned short)'E') & 0x8000)
fPlayerA -= (0.1f) * fElaspedTime;
如此一來,玩家的旋轉角度不再受不同的硬體限制,保持一定的速率進行旋轉!
std::chrono
: 處理時間的小幫手fPlayerA
的速度
關於玩家旋轉的小撇步就先到這裡~
後面將會介紹牆面渲染的小工具,
說起來,我擔心30天的文案應該不足以把我想推導的,想補充的內容都奉上,但後面會一直持續維護這個系列的~
路還很長,我們繼續走下去~